package com.base.api.service.commodity.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.base.api.dto.commodity.*;
import com.base.api.service.ClassifyBountyScreenSort;
import com.base.api.service.commodity.CommodityApiService;
import com.base.api.vo.commodity.ExplosiveVO;
import com.base.api.vo.commodity.BountyListVO;
import com.base.api.vo.commodity.GoodsShareVO;
import com.base.api.vo.commodity.OrderCommodityDetailVO;
import com.base.comm.CommUrls;
import com.base.mapper.voipmapper.SubscribersMapper;
import com.base.po.voip.Subscribers;
import com.base.result.PageUtils;
import com.base.result.ResponseResult;
import com.base.result.ResponseResultUtils;
import com.base.self.common.SelfRuntimeException;
import com.base.self.entity.Commodity;
import com.base.self.entity.CommodityCallPlan;
import com.base.self.entity.CommodityCallPlanDetail;
import com.base.self.es.model.CommodityEs;
import com.base.self.es.repository.CommodityEsRepository;
import com.base.self.mapper.CommodityCallPlanDetailMapper;
import com.base.self.mapper.CommodityCallPlanMapper;
import com.base.self.mapper.CommodityMapper;
import com.base.self.service.IPtCurrentService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Service
public class CommodityApiServiceImpl implements CommodityApiService {
    private final CommodityMapper commodityMapper;

    private final CommodityCallPlanMapper commodityCallPlanMapper;

    private final CommodityEsRepository commodityEsRepository;

    private final SubscribersMapper subscribersMapper;

    private final IPtCurrentService iPtCurrentService;

    private final CommodityCallPlanDetailMapper commodityCallPlanDetailMapper;

    public CommodityApiServiceImpl(CommodityMapper commodityMapper,
                                   CommodityCallPlanMapper commodityCallPlanMapper,
                                   CommodityEsRepository commodityEsRepository,
                                   SubscribersMapper subscribersMapper,
                                   IPtCurrentService iPtCurrentService,
                                   CommodityCallPlanDetailMapper commodityCallPlanDetailMapper) {
        this.commodityMapper = commodityMapper;
        this.commodityCallPlanMapper = commodityCallPlanMapper;
        this.commodityEsRepository = commodityEsRepository;
        this.subscribersMapper = subscribersMapper;
        this.iPtCurrentService = iPtCurrentService;
        this.commodityCallPlanDetailMapper = commodityCallPlanDetailMapper;
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult explosiveList(ExplosiveListDTO explosiveListDTO) {
        final Map<String, Object> data = PageUtils.getDateMap(() ->
                        commodityMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        explosiveListDTO.getOffset(),
                                        explosiveListDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<Commodity>()
                                        .select(
                                                Commodity::getId, Commodity::getCommodityName,
                                                Commodity::getCommodityRealPrice, Commodity::getCommodityMarketPrice,
                                                Commodity::getCommoditySales, Commodity::getCommodityShowPic
                                        )
                                        .eq(Commodity::getIsDel, 0)
                                        .eq(Commodity::getCommoditySubarea, 0)
                                        .orderByDesc(Commodity::getCommoditySales)
                        )
//                ,
//                page -> {
//                    List<Commodity> data1 = page.getRecords();
//                    return data1.stream().map(x -> new ExplosiveVO(
//                            x.getId(),
//                            x.getCommodityName(),
//                            x.getCommodityRealPrice(),
//                            x.getCommodityMarketPrice(),
//                            x.getCommoditySales(),
//                            x.getCommodityShowPic()));
//                }
                );
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult commodityDetail(CommodityDetailDTO commodityDetailDTO) {
        final Commodity commodity = commodityMapper.selectById(commodityDetailDTO.getId());
        Optional.ofNullable(commodity).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("商品信息错误")));
        commodity.setCommodityContextDetails(CommUrls.THISSERVER + "api/commodity/" + "commodityDetailLink?id=" + commodity.getId());
        return ResponseResultUtils.getResponseResultS("查询成功", commodity);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult orderCommodityDetail(OrderCommodityDetailDTO orderCommodityDetailDTO) {
        final Commodity commodity = commodityMapper.selectById(orderCommodityDetailDTO.getId());
        Optional.ofNullable(commodity).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("商品信息错误")));

        final OrderCommodityDetailVO orderCommodityDetailVO = new OrderCommodityDetailVO();
        orderCommodityDetailVO.setCommodityId(commodity.getId());
        orderCommodityDetailVO.setCommodityName(commodity.getCommodityName());
        orderCommodityDetailVO.setCommodityMarketPrice(commodity.getCommodityMarketPrice());
        orderCommodityDetailVO.setCommodityRealPrice(commodity.getCommodityRealPrice());
        orderCommodityDetailVO.setCommodityShowPic(commodity.getCommodityShowPic());

        if (commodity.getCommoditySubarea() == 0) {
            Integer callPlan = commodity.getCallPlan();
            final CommodityCallPlan commodityCallPlan = commodityCallPlanMapper.selectById(callPlan);
            Optional.ofNullable(commodityCallPlan).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("话费礼包错误")));

            orderCommodityDetailVO.setPlanId(commodityCallPlan.getId());
            orderCommodityDetailVO.setPlanName(commodityCallPlan.getPlanName());
            orderCommodityDetailVO.setPlanPic(commodityCallPlan.getPlanPic());
            orderCommodityDetailVO.setPlanPrice(commodityCallPlan.getPlanPrice());
        }

        return ResponseResultUtils.getResponseResultS("查询成功", orderCommodityDetailVO);
    }

    @Override
    @Transactional(readOnly = true)
    public String commodityDetailLink(HttpServletRequest request, CommodityDetailLinkDTO commodityDetailLinkDTO) {
        final Integer goodsId = commodityDetailLinkDTO.getId();
        if (goodsId == null || goodsId.compareTo(0) == 0) {
            return "self/goods_show";
        }
        final Commodity commodity = commodityMapper.selectById(goodsId);
        if (commodity != null) {
            request.setAttribute("context", commodity.getCommodityContextDetails());
        } else {
            request.setAttribute("context", "");
        }
        return "self/goods_show";
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult commodityBountyList(CommodityBountyListDTO commodityBountyListDTO) {
        final Map<String, Object> data = PageUtils.getDateMap(() ->
                        commodityMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        commodityBountyListDTO.getOffset(),
                                        commodityBountyListDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<Commodity>()
                                        .select(
                                                Commodity::getId, Commodity::getCommodityName,
                                                Commodity::getCommodityRealPrice, Commodity::getCommodityMarketPrice,
                                                Commodity::getCommoditySales, Commodity::getCommodityShowPic
                                        )
                                        .eq(Commodity::getCommoditySubarea, 0)
                                        .eq(Commodity::getIsDel, 0)
                                        .orderByDesc(Commodity::getCreateTime)
                        )
//                ,
//                page -> {
//                    List<Commodity> data1 = page.getRecords();
//                    return data1.stream().map(x -> new BountyListVO(
//                            x.getId(),
//                            x.getCommodityName(),
//                            x.getCommodityRealPrice(),
//                            x.getCommodityMarketPrice(),
//                            x.getCommoditySales(),
//                            x.getCommodityShowPic()));
//                }
                );
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult commodityBountyScreen(CommodityBountyScreenDTO commodityBountyScreenDTO) {
        final Integer classifyId1 = commodityBountyScreenDTO.getClassifyId1();
        final Integer classifyId2 = commodityBountyScreenDTO.getClassifyId2();
        final Map<String, Object> data = PageUtils.getDateMap(() ->
                        commodityMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        commodityBountyScreenDTO.getOffset(),
                                        commodityBountyScreenDTO.getLimit()
                                ),
                                new LambdaQueryWrapper<Commodity>()
                                        .select(
                                                Commodity::getId, Commodity::getCommodityName,
                                                Commodity::getCommodityRealPrice, Commodity::getCommodityMarketPrice,
                                                Commodity::getCommoditySales, Commodity::getCommodityShowPic
                                        )
                                        .eq(Optional.ofNullable(classifyId1).isPresent(), Commodity::getCommodityClassifyLevel1, classifyId1)
                                        .eq(Optional.ofNullable(classifyId2).isPresent(), Commodity::getCommodityClassifyLevel2, classifyId2)
                                        .eq(Commodity::getCommoditySubarea, commodityBountyScreenDTO.getCommoditySubarea())
                                        .eq(Commodity::getIsDel, 0)
                                        .orderByDesc(Commodity::getCreateTime)
                        )
//                ,
//                page -> {
//                    List<Commodity> data1 = page.getRecords();
//                    return data1.stream().map(x -> new BountyListVO(
//                            x.getId(),
//                            x.getCommodityName(),
//                            x.getCommodityRealPrice(),
//                            x.getCommodityMarketPrice(),
//                            x.getCommoditySales(),
//                            x.getCommodityShowPic()));
//                }
                );
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }


    @Override
    @Transactional(readOnly = true)
    public ResponseResult commodityBountySearch(CommoditySearchDTO commoditySearchDTO) {
        try {
            QueryBuilder customerQuery = QueryBuilders.boolQuery()
                    .must(QueryBuilders.matchQuery("commodityName", commoditySearchDTO.getCommodityName()));
            org.springframework.data.domain.Page<CommodityEs> page = commodityEsRepository.search(
                    customerQuery,
                    PageRequest.of(commoditySearchDTO.getOffset() - 1, commoditySearchDTO.getLimit())
            );
            Map<String, Object> data = new HashMap<>();
            data.put("total", page.getTotalElements());
            data.put("rows", page.getContent());
            return ResponseResultUtils.getResponseResultS("查询成功", data);
        }catch (Exception e) {/*ES异常走数据库查询*/
            final Map<String, Object> data = PageUtils.getDateMap(() ->
                            commodityMapper.selectPage(
                                    PageUtils.getPage(
                                            new Page<>(),
                                            commoditySearchDTO.getOffset(),
                                            commoditySearchDTO.getLimit()
                                    ),
                                    new LambdaQueryWrapper<Commodity>()
                                            .select(
                                                    Commodity::getId, Commodity::getCommodityName,
                                                    Commodity::getCommodityRealPrice, Commodity::getCommodityMarketPrice,
                                                    Commodity::getCommoditySales, Commodity::getCommodityShowPic
                                            )
                                            .eq(Commodity::getIsDel, 0)
                                            .likeRight(Commodity::getCommodityName, commoditySearchDTO.getCommodityName())
                            )
//                    ,
//                    page -> {
//                        List<Commodity> data1 = page.getRecords();
//                        return data1.stream().map(x -> new BountyListVO(
//                                x.getId(),
//                                x.getCommodityName(),
//                                x.getCommodityRealPrice(),
//                                x.getCommodityMarketPrice(),
//                                x.getCommoditySales(),
//                                x.getCommodityShowPic()));
//                    }
                    );
            return ResponseResultUtils.getResponseResultS("查询成功", data);
        }

    }

    @Override
    @Transactional(readOnly = true)
    public ResponseResult classifyBountyScreen(ClassifyBountyScreenDTO classifyBountyScreenDTO) {
        final Integer classifyId1 = classifyBountyScreenDTO.getClassifyId1();
        final String sortWay = classifyBountyScreenDTO.getSortWay();

        String[] sortWayArr = sortWay.split(";");

        Map<String, List<ClassifyBountyScreenSort>> classifyBountyScreenSortMap = Arrays.stream(sortWayArr).map(x -> {
            String[] xArr = x.split(":");
            if (xArr.length < 2) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("排序方式错误[:]"));
            }
            if (!StringUtils.endsWithAny(xArr[1], "DESC", "ASC")) {
                throw new SelfRuntimeException(ResponseResultUtils.getResponseResultF("排序值错误['ASC','DESC']"));
            }
            if ("0".equals(xArr[0])/*特殊,默认ASC*/) {
                return new ClassifyBountyScreenSort(xArr[0], "ASC");
            }
            ClassifyBountyScreenSort classifyBountyScreenSort = new ClassifyBountyScreenSort();
            classifyBountyScreenSort.setSortKey(xArr[0]);
            classifyBountyScreenSort.setSortValue(xArr[1]);
            return classifyBountyScreenSort;
        }).collect(Collectors.groupingBy(ClassifyBountyScreenSort::getSortValue));

        List<ClassifyBountyScreenSort> desc = classifyBountyScreenSortMap.get("DESC");
        List<ClassifyBountyScreenSort> asc = classifyBountyScreenSortMap.get("ASC");

        AtomicReference<List<String>> atomicReferenceDescStr = new AtomicReference<>(new ArrayList<>());
        AtomicReference<List<String>> atomicReferenceAscStr = new AtomicReference<>(new ArrayList<>());
        AtomicReference<Boolean> isAll = new AtomicReference<>(false);
        if (CollectionUtils.isNotEmpty(desc)) {
            atomicReferenceDescStr.set(desc.stream().sorted(Comparator.comparing(ClassifyBountyScreenSort::getSort)).map(ClassifyBountyScreenSort::getSortKey).collect(Collectors.toList()));
        }
        if (CollectionUtils.isNotEmpty(asc)) {
            atomicReferenceAscStr.set(asc.stream().sorted(Comparator.comparing(ClassifyBountyScreenSort::getSort)).map(ClassifyBountyScreenSort::getSortKey).collect(Collectors.toList()));

            isAll.set("0".equals(asc.get(0).getSortKey()));
        }

        final Map<String, Object> data = PageUtils.getDateMap(() ->
                        commodityMapper.selectPage(
                                PageUtils.getPage(
                                        new Page<>(),
                                        classifyBountyScreenDTO.getOffset(),
                                        classifyBountyScreenDTO.getLimit()
                                ),
                                new QueryWrapper<Commodity>()
                                        .select(
                                                "id", "commodity_name", "commodity_real_price",
                                                "commodity_market_price", "commodity_sales", "commodity_show_pic",
                                                "create_time"
                                        )
                                        .eq(classifyId1 != 0, "commodity_classify_level1", classifyId1)
                                        .eq("is_del", 0)

                                        .orderByDesc(CollectionUtils.isNotEmpty(atomicReferenceDescStr.get()),
                                                StringUtils.join(atomicReferenceDescStr.get().toArray(), ","))

                                        .orderByAsc(CollectionUtils.isNotEmpty(atomicReferenceAscStr.get())
                                                        && !isAll.get(),
                                                StringUtils.join(atomicReferenceAscStr.get().toArray(), ","))

                                        .orderByAsc(isAll.get(),
                                                "commodity_sales", "create_time", "commodity_real_price")
                        )
//                ,
//                page -> {
//                    List<Commodity> data1 = page.getRecords();
//                    return data1.stream().map(x -> new BountyListVO(
//                            x.getId(),
//                            x.getCommodityName(),
//                            x.getCommodityRealPrice(),
//                            x.getCommodityMarketPrice(),
//                            x.getCommoditySales(),
//                            x.getCommodityShowPic()));
//                }
                );
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }

    @Override
    public ResponseResult goodsShare(GoodsShareDTO goodsShareDTO) {
        final Commodity commodity = commodityMapper.selectById(goodsShareDTO.getId());
        Optional.ofNullable(commodity).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("商品信息错误")));
        final Subscribers subscribers = subscribersMapper.selectByPrimaryKey(goodsShareDTO.getUserId());
        Optional.ofNullable(subscribers).orElseThrow(() -> new SelfRuntimeException(ResponseResultUtils.getResponseResultF("用户不存在")));

        final GoodsShareVO goodsShareVO = new GoodsShareVO(
                commodity.getId(),
                commodity.getCommodityName(),
                commodity.getCommodityRealPrice(),
                commodity.getCommodityMarketPrice(),
                commodity.getCommodityShowPic(),
                iPtCurrentService.chaTP(subscribers.getId(), String.valueOf(commodity.getId()))
        );
        return ResponseResultUtils.getResponseResultS("查询成功", goodsShareVO);
    }

    @Override
    public ResponseResult commodityCallPlanDetail(CommodityCallPlanDetailDTO commodityCallPlanDetailDTO) {
        List<CommodityCallPlanDetail> data = commodityCallPlanDetailMapper.selectList(new LambdaQueryWrapper<CommodityCallPlanDetail>()
                .eq(CommodityCallPlanDetail::getCallPlan, commodityCallPlanDetailDTO.getCallPlan())
                .eq(CommodityCallPlanDetail::getIsDel, 0)
        );
        return ResponseResultUtils.getResponseResultS("查询成功", data);
    }
}
